package com.sailfish.springbootdemo.controller.db1;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.h3c.ssoAuth.entity.CodeAuthResponse;
import com.h3c.ssoAuth.util.SSOUtil;
import com.sailfish.springbootdemo.controller.db4.Role;
import com.sailfish.springbootdemo.dao.db4.RoleDao;
import com.sailfish.springbootdemo.dao.db4.UserDao;
import com.sailfish.springbootdemo.dao.db4.UsergroupDao;
import com.sailfish.springbootdemo.dao.db5.EmpTAdmpAdgroupDao;
import com.sailfish.springbootdemo.dao.db5.EmpTDepartmentsDao;
import com.sailfish.springbootdemo.dao.db5.EmpTPublicStaffDao;
import com.sailfish.springbootdemo.pojo.Result;
import com.sailfish.springbootdemo.pojo.db4.LoginRecord;
import com.sailfish.springbootdemo.pojo.db4.User;
import com.sailfish.springbootdemo.pojo.db4.Usergroup;
import com.sailfish.springbootdemo.pojo.db5.EmpTAdmpAdgroup;
import com.sailfish.springbootdemo.pojo.db5.EmpTDepartments;
import com.sailfish.springbootdemo.pojo.db5.EmpTPublicStaff;
import com.sailfish.springbootdemo.service.db4.LoginRecordService;
import com.sailfish.springbootdemo.utils.CommonUtils;
import com.sailfish.springbootdemo.utils.HttpUtil;
import com.sailfish.springbootdemo.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/sso")
@CrossOrigin
public class SsoController {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private EmpTPublicStaffDao empTPublicStaffDao;

    @Value("${personal.config.jwt.expiration-time}")
    private Integer expirationTime;

    @Value("${personal.config.jwt.sign}")
    private String sign;

    @Value("${personal.config.sso.client-id}")
    private String clientId;

    @Value("${personal.config.sso.secret}")
    private String secret;

    @Value("${personal.config.sso.sso-server}")
    private String ssoServer;

    @Value("${personal.config.sso.trusted-redirect-uri}")
    private String trustedRedirectUri;

    @Value("${personal.config.env}")
    private String env;

    @Value("${personal.config.ip-check}")
    private String ipCheck;

    @Value("${personal.config.get-ip-address-api}")
    private String getIpAddressApi;

    @Autowired
    private EmpTDepartmentsDao empTDepartmentsDao;

    @Autowired
    private EmpTAdmpAdgroupDao empTAdmpAdgroupDao;

    @Autowired
    private UsergroupDao usergroupDao;

    @Autowired
    private LoginRecordService loginRecordService;

    @PostMapping("/getSsoUrl")
    public String getSsoUrl(String url) {
        try {
            String redirect_uri = trustedRedirectUri + url;
            SSOUtil.init(ssoServer, clientId, secret, trustedRedirectUri);
            String ssoLoginUrl = SSOUtil.generateLoginUrl(redirect_uri);
            System.out.println("sso登录地址：" + ssoLoginUrl);
            return ssoLoginUrl;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    @PostMapping("/generateLogoutUrl")
    public String generateLogoutUrl(String url) {
        try {
            String redirect_uri = trustedRedirectUri + url;
            SSOUtil.init(ssoServer, clientId, secret, trustedRedirectUri);
            String s = SSOUtil.generateLogoutUrl(redirect_uri);
            System.out.println("退出登录地址：" + s);
            return s;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    @PostMapping("/getUserId")
    public Result getUserId(String h3c_ticket, HttpServletRequest request) {
        try {
            LoginRecord loginRecord = new LoginRecord();
            if (h3c_ticket == null || "".equals(h3c_ticket)) {
                return ResultUtil.errorNoPermission(null);
            }
            String ipAddress = CommonUtils.getClientIpAddress(request);
            System.out.println("ipAddress=" + ipAddress);
            if (ipAddress == null || "".equals(ipAddress)) {
                return ResultUtil.error(500, "未获取到ip", "Not Get IP", null);
            }
            SSOUtil.init(ssoServer, clientId, secret, trustedRedirectUri);
            CodeAuthResponse codeAuthResponse = SSOUtil.codeAuth(h3c_ticket);
            System.out.println("codeAuthResponse返回的状态码为：" + codeAuthResponse.getResponseCode());
            if (200 == codeAuthResponse.getResponseCode()) {
                String userId = codeAuthResponse.getUser_id();

                System.out.println("SSO登录返回的domainAccount==================" + userId);

                User user = userDao.getUserInfoByDomainAccount(userId);
                if (user == null) {
                    return ResultUtil.error(500, "未找到对应用户,请联系管理员添加", "Not Found User", null);
                }

                EmpTPublicStaff empTPublicStaffByDomainAccount = empTPublicStaffDao.getEmpTPublicStaffByDomainAccount(userId);
                if (empTPublicStaffByDomainAccount == null) {
                    return ResultUtil.error(500, "未找到对应用户,可能用户已离职或者Emp表未同步", "Not Found User", null);
                }

                /*if (user.getIsInner() == 2) {
                    // h3c外场人员
                    if ((user.getBelongPcb() == null || "".equals(user.getBelongPcb().toString())) && (user.getBelongPcba() == null || "".equals(user.getBelongPcba().toString()))) {
                        return ResultUtil.error(500, "当前用户是外场人员，请联系管理员设置所属板厂或CM厂", "User Set Error", null);
                    }
                }*/

                EmpTDepartments empTDepartmentsByDeptCode = empTDepartmentsDao.getEmpTDepartmentsByDeptCode(empTPublicStaffByDomainAccount.getDeptCode());
                if (empTDepartmentsByDeptCode == null) {
                    return ResultUtil.error(500, "未获取到当前用户的部门号", "Not Get DeptCode", null);
                }

                String groupStr = "";

                loginRecord.setUserId(user.getUserId());
                loginRecord.setIpAddress(ipAddress);

                if (ipCheck != null && ipCheck.contains("pro")) {
                    // h3c 正式环境,检索ip
                    String typeId = empTDepartmentsByDeptCode.getTypeId();
                    String res = HttpUtil.sendGetRequest(getIpAddressApi + "?address=" + ipAddress);
                    System.out.println("getIpAddressApi:return" + res);
                    JSONObject resObj = JSONObject.parseObject(res);
                    if ("200".equals(resObj.get("statusCode").toString())) {
                        groupStr = resObj.getJSONObject("data").getString("group");
                        // 含  黄云、黄区、红云、红区  为研发，其余非研发
                        if ("RD".equals(typeId)) {
                            // 研发段 只能在 研发段 登
                            if (!groupStr.contains("黄云") && !groupStr.contains("黄区") && !groupStr.contains("红云") && !groupStr.contains("红区")) {
                                loginRecord.setNetworkSeg(groupStr);
                                loginRecord.setFailReason("当前用户研发，登录ip非研发，禁止登陆");
                                loginRecord.setLoginResult("失败");
                                return ResultUtil.error(500, "当前用户研发，登录ip非研发，禁止登陆", "Forbidden Login", null);
                            }
                        } else {
                            // 非研发段 只能在 非研发段 登
                            if (groupStr.contains("黄云") || groupStr.contains("黄区") || groupStr.contains("红云") || groupStr.contains("红区")) {
                                loginRecord.setNetworkSeg(groupStr);
                                loginRecord.setFailReason("当前用户非研发，登录ip研发，禁止登陆");
                                loginRecord.setLoginResult("失败");
                                return ResultUtil.error(500, "当前用户非研发，登录ip研发，禁止登陆", "Forbidden Login", null);
                            }
                        }
                    } else {
                        loginRecord.setNetworkSeg(groupStr);
                        loginRecord.setFailReason(resObj.get("msg").toString());
                        loginRecord.setLoginResult("失败");
                        return ResultUtil.error(500, resObj.get("msg").toString(), resObj.get("msg").toString(), null);
                    }
                }

                Map<String, Object> map = new HashMap<>();
                Map<String, Object> userInfo = new HashMap<>();


                userInfo.put("dashboard", user.getDashboard());
                userInfo.put("userId", user.getUserId());
                userInfo.put("nickNameCn", empTPublicStaffByDomainAccount.getPreferredName());
                userInfo.put("nickNameEn", empTPublicStaffByDomainAccount.getPreferredName());

                String roleNameStr = "";
                String roleStrSys = user.getRoleSys();
                String roleStrBase = user.getRoleBase();
                String roleStrTech = user.getRoleTech();
                String[] roleArrSys = (roleStrSys != null && !"".equals(roleStrSys)) ? roleStrSys.split(",") : null;
                String[] roleArrBase = (roleStrBase != null && !"".equals(roleStrBase)) ? roleStrBase.split(",") : null;
                String[] roleArrTech = (roleStrTech != null && !"".equals(roleStrTech)) ? roleStrTech.split(",") : null;
                if(roleArrSys != null){
                    for (String s : roleArrSys) {
                        Role r = roleDao.getRoleById(Integer.parseInt(s));
                        if (r != null) {
                            String roleNameCn = r.getRoleNameCn();
                            if (roleNameCn != null && !"".equals(roleNameCn)) {
                                roleNameStr = roleNameStr + roleNameCn + ",";
                            }
                        }
                    }
                }
                if(roleArrBase != null){
                    for (String s : roleArrBase) {
                        Role r = roleDao.getRoleById(Integer.parseInt(s));
                        if (r != null) {
                            String roleNameCn = r.getRoleNameCn();
                            if (roleNameCn != null && !"".equals(roleNameCn)) {
                                roleNameStr = roleNameStr + roleNameCn + ",";
                            }
                        }
                    }
                }
                if(roleArrTech != null){
                    for (String s : roleArrTech) {
                        Role r = roleDao.getRoleById(Integer.parseInt(s));
                        if (r != null) {
                            String roleNameCn = r.getRoleNameCn();
                            if (roleNameCn != null && !"".equals(roleNameCn)) {
                                roleNameStr = roleNameStr + roleNameCn + ",";
                            }
                        }
                    }
                }

                // 上面为基本的用户角色配置
                // 以下为用户组中的角色配置
                String member = user.getDisplayName() + " " + user.getNotesId();
                List<EmpTAdmpAdgroup> empTAdmpAdgroupList = empTAdmpAdgroupDao.getByMember(member);
                for (EmpTAdmpAdgroup empTAdmpAdgroup : empTAdmpAdgroupList) {
                    String group_name = empTAdmpAdgroup.getGroup_name();
                    if(group_name != null && !"".equals(group_name)){
                        Usergroup usergroup = usergroupDao.getByName(group_name);
                        if(usergroup != null){
                            List<Role> roleListByUserGroupId = roleDao.getRoleListByUserGroupId(usergroup.getId());
                            for (Role role : roleListByUserGroupId) {
                                String roleNameCn = role.getRoleNameCn();
                                if (roleNameCn != null && !"".equals(roleNameCn)) {
                                    roleNameStr = roleNameStr + roleNameCn + ",";
                                }
                            }
                        }
                    }
                }

                if (roleNameStr.length() > 0) {
                    roleNameStr = roleNameStr.substring(0, roleNameStr.length() - 1);
                }

                if ("".equals(roleNameStr)) {
                    loginRecord.setNetworkSeg(groupStr);
                    loginRecord.setFailReason("该用户未配置角色，请联系管理员配置");
                    loginRecord.setLoginResult("失败");
                    return ResultUtil.error(500, "该用户未配置角色，请联系管理员配置", "Not Set Role", null);
                }

                userInfo.put("role", roleNameStr);

                map.put("userInfo", userInfo);

                List<Integer> roleList = new ArrayList<>();
                if(roleArrSys != null){
                    for (String s : roleArrSys) {
                        roleList.add(Integer.parseInt(s));
                    }
                }
                if(roleArrBase != null){
                    for (String s : roleArrBase) {
                        roleList.add(Integer.parseInt(s));
                    }
                }
                if(roleArrTech != null){
                    for (String s : roleArrTech) {
                        roleList.add(Integer.parseInt(s));
                    }
                }

                Calendar instance = Calendar.getInstance();
                instance.add(Calendar.MINUTE, expirationTime);
                String token = JWT.create()
                        .withHeader(map)//添加头部
                        .withClaim("userId", user.getUserId().toString())//添加payload
                        .withClaim("userName", user.getUserName())
                        .withClaim("password", user.getPassword())
                        .withClaim("role", user.getRole())
                        .withClaim("roleList", roleList)
                        .withClaim("domainAccount", user.getDomainAccount())
                        .withClaim("isInner", user.getIsInner() != null && !"".equals(user.getIsInner().toString()) ? user.getIsInner().toString() : "")
                        .withClaim("belongPcb", user.getBelongPcb() != null && !"".equals(user.getBelongPcb().toString()) ? user.getBelongPcb().toString() : "")
                        .withClaim("belongPcba", user.getBelongPcba() != null && !"".equals(user.getBelongPcba().toString()) ? user.getBelongPcba().toString() : "")
                        .withClaim("pcbas", user.getPcbas() != null && !"".equals(user.getPcbas()) ? user.getPcbas() : "")
                        .withClaim("pcbs", user.getPcbs() != null && !"".equals(user.getPcbs()) ? user.getPcbs() : "")
                        .withClaim("networkSeg", groupStr)
                        .withClaim("ipAddress", ipAddress)
                        .withExpiresAt(instance.getTime())//设置过期时间
                        .sign(Algorithm.HMAC256(sign));//设置签名 密钥
                map.put("token", token);

                loginRecord.setNetworkSeg(groupStr);
                loginRecord.setFailReason("");
                loginRecord.setLoginResult("成功");

                loginRecordService.addLoginRecord(loginRecord);

                return ResultUtil.success(map);
            }
            return ResultUtil.error(500, codeAuthResponse.getError(), codeAuthResponse.getError(), null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    /**
     * 给第三方平台调用 访问指定页面的url [未完成]
     */
    @GetMapping("/ssoLoginByOtherPlatform")
    public Result ssoLoginByOtherPlatform(String url, HttpServletRequest request) {
        try {
            if (url == null || "".equals(url)) {
                return ResultUtil.error(500, "错误url", "Error url", null);
            }
            String redirect_uri = trustedRedirectUri + url;
            SSOUtil.init(ssoServer, clientId, secret, trustedRedirectUri);
            String ssoLoginUrl = SSOUtil.generateLoginUrl(redirect_uri);
            System.out.println("ssoLoginByOtherPlatform登录地址：" + ssoLoginUrl);
            String ipAddress = CommonUtils.getClientIpAddress(request);
            System.out.println("ipAddress=" + ipAddress);
            if (ipAddress == null || "".equals(ipAddress)) {
                return ResultUtil.error(500, "未获取到ip", "Not Get IP", null);
            }
            String finalUrl = CommonUtils.getFinalUrl(ssoLoginUrl);
            System.out.println("finalUrl重定向url：" + finalUrl);
            // 解析 ssoLoginUrl  得到 h3c_ticket 参数值
            Map<String, String> parameters = CommonUtils.getURLParameters(finalUrl);
            String h3c_ticket = "";
            for (Map.Entry<String, String> entry : parameters.entrySet()) {
                System.out.println(entry.getKey() + ": " + entry.getValue());
                if ("h3c_ticket".equals(entry.getKey())) {
                    h3c_ticket = entry.getValue();
                    break;
                }
            }
            if (h3c_ticket == null || "".equals(h3c_ticket)) {
                return ResultUtil.error(500, "未获取到h3c_ticket", "Not Get h3c_ticket", null);
            }
            CodeAuthResponse codeAuthResponse = SSOUtil.codeAuth(h3c_ticket);
            System.out.println("codeAuthResponse返回的状态码为：" + codeAuthResponse.getResponseCode());
            if (200 == codeAuthResponse.getResponseCode()) {
                String userId = codeAuthResponse.getUser_id();

                System.out.println("SSO登录返回的domainAccount==================" + userId);

                User user = userDao.getUserInfoByDomainAccount(userId);
                if (user == null) {
                    return ResultUtil.error(500, "未找到对应用户,请联系管理员添加", "Not Found User", null);
                }

                EmpTPublicStaff empTPublicStaffByDomainAccount = empTPublicStaffDao.getEmpTPublicStaffByDomainAccount(userId);
                if (empTPublicStaffByDomainAccount == null) {
                    return ResultUtil.error(500, "未找到对应用户,可能用户已离职或者Emp表未同步", "Not Found User", null);
                }

                if (user.getIsInner() == 2) {
                    // h3c外场人员
                    if ((user.getBelongPcb() == null || "".equals(user.getBelongPcb().toString())) && (user.getBelongPcba() == null || "".equals(user.getBelongPcba().toString()))) {
                        return ResultUtil.error(500, "当前用户是外场人员，请联系管理员设置所属板厂或CM厂", "User Set Error", null);
                    }
                }

                EmpTDepartments empTDepartmentsByDeptCode = empTDepartmentsDao.getEmpTDepartmentsByDeptCode(empTPublicStaffByDomainAccount.getDeptCode());
                if (empTDepartmentsByDeptCode == null) {
                    return ResultUtil.error(500, "未获取到当前用户的部门号", "Not Get DeptCode", null);
                }

                if ("h3c_pro".equals(ipCheck)) {
                    // h3c 正式环境,检索ip
                    String typeId = empTDepartmentsByDeptCode.getTypeId();
                    String res = HttpUtil.sendGetRequest(getIpAddressApi + "?address=" + ipAddress);
                    System.out.println("getIpAddressApi:return" + res);
                    JSONObject resObj = JSONObject.parseObject(res);
                    if ("200".equals(resObj.get("statusCode").toString())) {
                        String groupStr = resObj.getJSONObject("data").getString("group");
                        // 含  黄云、黄区、红云、红区  为研发，其余非研发
                        if ("RD".equals(typeId)) {
                            // 研发段 只能在 研发段 登
                            if (!groupStr.contains("黄云") && !groupStr.contains("黄区") && !groupStr.contains("红云") && !groupStr.contains("红区")) {
                                return ResultUtil.error(500, "当前用户研发，登录ip非研发，禁止登陆", "Forbidden Login", null);
                            }
                        } else {
                            // 非研发段 只能在 非研发段 登
                            if (groupStr.contains("黄云") || groupStr.contains("黄区") || groupStr.contains("红云") || groupStr.contains("红区")) {
                                return ResultUtil.error(500, "当前用户非研发，登录ip研发，禁止登陆", "Forbidden Login", null);
                            }
                        }
                    }
                    return ResultUtil.error(500, resObj.get("msg").toString(), resObj.get("msg").toString(), null);
                }

                Map<String, Object> map = new HashMap<>();
                Map<String, Object> userInfo = new HashMap<>();


                userInfo.put("dashboard", user.getDashboard());
                userInfo.put("userId", user.getUserId());
                userInfo.put("nickNameCn", empTPublicStaffByDomainAccount.getPreferredName());
                userInfo.put("nickNameEn", empTPublicStaffByDomainAccount.getPreferredName());

                String roleNameStr = "";
                String roleStr = user.getRole();
                String[] roleArr = roleStr.split(",");
                for (String s : roleArr) {
                    Role r = roleDao.getRoleById(Integer.parseInt(s));
                    if (r != null) {
                        String roleNameCn = r.getRoleNameCn();
                        if (roleNameCn != null && !"".equals(roleNameCn)) {
                            roleNameStr = roleNameStr + roleNameCn + ",";
                        }
                    }
                }

                // 上面为基本的用户角色配置
                // 以下为用户组中的角色配置
                String member = user.getDisplayName() + " " + user.getNotesId();
                List<EmpTAdmpAdgroup> empTAdmpAdgroupList = empTAdmpAdgroupDao.getByMember(member);
                for (EmpTAdmpAdgroup empTAdmpAdgroup : empTAdmpAdgroupList) {
                    String group_name = empTAdmpAdgroup.getGroup_name();
                    if(group_name != null && !"".equals(group_name)){
                        Usergroup usergroup = usergroupDao.getByName(group_name);
                        if(usergroup != null){
                            List<Role> roleListByUserGroupId = roleDao.getRoleListByUserGroupId(usergroup.getId());
                            for (Role role : roleListByUserGroupId) {
                                String roleNameCn = role.getRoleNameCn();
                                if (roleNameCn != null && !"".equals(roleNameCn)) {
                                    roleNameStr = roleNameStr + roleNameCn + ",";
                                }
                            }
                        }
                    }
                }

                if (roleNameStr.length() > 0) {
                    roleNameStr = roleNameStr.substring(0, roleNameStr.length() - 1);
                }
                if ("".equals(roleNameStr)) {
                    return ResultUtil.error(500, "该用户未配置角色，请联系管理员配置", "Not Set Role", null);
                }

                userInfo.put("role", roleNameStr);

                map.put("userInfo", userInfo);


                Calendar instance = Calendar.getInstance();
                instance.add(Calendar.MINUTE, expirationTime);
                String token = JWT.create()
                        .withHeader(map)//添加头部
                        .withClaim("userId", user.getUserId().toString())//添加payload
                        .withClaim("userName", user.getUserName())
                        .withClaim("password", user.getPassword())
                        .withClaim("role", user.getRole())
                        .withClaim("domainAccount", user.getDomainAccount())
                        .withClaim("isInner", user.getIsInner() != null && !"".equals(user.getIsInner().toString()) ? user.getIsInner().toString() : "")
                        .withClaim("belongPcb", user.getBelongPcb() != null && !"".equals(user.getBelongPcb().toString()) ? user.getBelongPcb().toString() : "")
                        .withClaim("belongPcba", user.getBelongPcba() != null && !"".equals(user.getBelongPcba().toString()) ? user.getBelongPcba().toString() : "")
                        .withExpiresAt(instance.getTime())//设置过期时间
                        .sign(Algorithm.HMAC256(sign));//设置签名 密钥
                map.put("token", token);

                return ResultUtil.success(map);
            }
            return ResultUtil.error(500, codeAuthResponse.getError(), codeAuthResponse.getError(), null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }
}
